Skip to content

Conversation

@soyuka
Copy link
Member

@soyuka soyuka commented Dec 9, 2025

Q A
Branch? main
Tickets na
License MIT
Doc PR needed

Rework of #7458

Now with a simpler approach, this gives the ability to add McpTool (upcoming McpResource) to any API Platform environment giving access to:

  • automatic input JSON Schema's (waiting for feat: Add output schema support to MCP tools modelcontextprotocol/php-sdk#153 for output schema compatiblity)
  • automatic structured content
  • reuses the Symfony serializer under the hood (with all the capabilities of API Platform including optional iris using item_uri_template)
  • allows to return a custom CallToolResult (from the php-sdk itself for images, sound etc.)
  • ability to reuse Symfony validation constraints as usual
  • works with doctrine entities if needed (calls the provider and the processor on demand)
  • integrates with the symfony security features

TODO:

  • test with #[McpTool] attribute
  • test using an entity
  • test custom CallToolResult content
  • test validation
  • test #[McpResource]

Because MCP uses JSON-RPC under the hood with some particular response objects (from php-sdk) we can not change returned headers yet (we'll work on an extension point).

@soyuka soyuka force-pushed the mcp-bundle-integration branch from c0836f7 to 512c885 Compare January 11, 2026 21:44
@soyuka soyuka force-pushed the mcp-bundle-integration branch from 512c885 to a7b8b8f Compare January 12, 2026 06:44
@soyuka soyuka force-pushed the mcp-bundle-integration branch from d136520 to b904a0d Compare January 12, 2026 08:37
Copy link
Contributor

@rvanlaak rvanlaak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exciting that the mcp repo's schema PR is merged now, and you're able to spend time on API Platform integration.

Tried reviewing this PR without checking it out and testing it, so please feel free to ignore all my comments / suggestions / nitpicks 🙌 Just trying to provide you with another pov at some classes.

true
);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw LogicException here?

}
}

return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As tell-dont-ask implies we expect creation of the operation, edge cases could lead to clear exceptions on how to resolve those. What about dropping nullability on the return typehint, and throw LogicException here?

Put::class,
ApiResource::class,
] as $class) {
$container->registerAttributeForAutoconfiguration($class, static function (ChildDefinition $definition): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about letting all these classes extend a Resource interface, and solely register the tag on that class? Or even better; consider the FQCN of that interface as the tag? Interface composition would be great way to document behaviors.

use Symfony\Component\WebLink\Link as WebLink;

#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class McpTool extends HttpOperation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the tool really the operation? Feels like there should be something in the middle of tool handling as well, to allow (like the symfony ai implementations) dispatch specific events around the handling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants